using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using System;
using KrasDD.Dtos;

namespace KrasDD.Filters
{
    /// <summary>
    /// API响应格式统一过滤器
    /// </summary>
    public class ApiResponseFilter : ActionFilterAttribute
    {
        /// <summary>
        /// 在Action执行前调用
        /// </summary>
        /// <param name="context">Action执行上下文</param>
        public override void OnActionExecuting(ActionExecutingContext context)
        {
            // 处理模型验证错误
            if (!context.ModelState.IsValid)
            {
                var errorMessages = context.ModelState.SelectMany(l => l.Value.Errors).Select(l => l.ErrorMessage).Where(l => !string.IsNullOrWhiteSpace(l)).ToList();
                var errorMessage = string.Join("; ", errorMessages);
                context.Result = new ObjectResult(ApiResponse<object>.Fail(errorMessage, 400))
                {
                    StatusCode = 200 // 统一返回200状态码，错误信息在body中
                };
            }
        }

        /// <summary>
        /// 在Action执行后调用
        /// </summary>
        /// <param name="context">Action执行上下文</param>
        public override void OnActionExecuted(ActionExecutedContext context)
        {
            // 如果有异常，则处理异常
            if (context.Exception != null)
            {
                // 创建异常响应
                context.Result = new ObjectResult(ApiResponse<object>.Exception(
                    context.Exception.Message,
                    context.Exception.StackTrace ?? "No stack trace available",
                    500))
                {
                    StatusCode = 200 // 统一返回200状态码，错误信息在body中
                };

                // 标记异常已处理
                context.ExceptionHandled = true;
                return;
            }

            // 如果已经有结果，则处理结果
            if (context.Result is ObjectResult objectResult)
            {
                // 根据状态码创建统一响应
                switch (objectResult.StatusCode)
                {
                    case 200:
                    case 201:
                        // 对于成功响应，包装数据
                        context.Result = new ObjectResult(ApiResponse<object>.Ok(objectResult.Value ?? new object()))
                        {
                            StatusCode = 200
                        };
                        break;
                    case 400:
                        context.Result = new ObjectResult(ApiResponse<object>.Fail(objectResult.Value?.ToString() ?? "请求参数错误", 400))
                        {
                            StatusCode = 200 // 统一返回200状态码，错误信息在body中
                        };
                        break;
                    case 401:
                        context.Result = new ObjectResult(ApiResponse<object>.Fail(objectResult.Value?.ToString() ?? "未授权访问", 401))
                        {
                            StatusCode = 200 // 统一返回200状态码，错误信息在body中
                        };
                        break;
                    case 404:
                        context.Result = new ObjectResult(ApiResponse<object>.Fail(objectResult.Value?.ToString() ?? "资源未找到", 404))
                        {
                            StatusCode = 200 // 统一返回200状态码，错误信息在body中
                        };
                        break;
                    default:
                        // 其他状态码保持原样
                        break;
                }
            }
            // 处理其他类型的返回结果
            else if (context.Result is StatusCodeResult statusCodeResult)
            {
                // 根据状态码创建统一响应
                switch (statusCodeResult.StatusCode)
                {
                    case 204: // No Content
                        context.Result = new ObjectResult(ApiResponse<object>.Ok(new object()))
                        {
                            StatusCode = 200
                        };
                        break;
                    case 400:
                        context.Result = new ObjectResult(ApiResponse<object>.Fail("请求参数错误", 400))
                        {
                            StatusCode = 200
                        };
                        break;
                    case 401:
                        context.Result = new ObjectResult(ApiResponse<object>.Fail("未授权访问", 401))
                        {
                            StatusCode = 200
                        };
                        break;
                    case 404:
                        context.Result = new ObjectResult(ApiResponse<object>.Fail("资源未找到", 404))
                        {
                            StatusCode = 200
                        };
                        break;
                    default:
                        // 其他状态码保持原样
                        break;
                }
            }
            // 处理空结果
            else if (context.Result == null)
            {
                context.Result = new ObjectResult(ApiResponse<object>.Ok(new object()))
                {
                    StatusCode = 200
                };
            }
        }
    }
}